package com.jichangxiu.server.platform.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jichangxiu.common.entity.bo.PageData;
import com.jichangxiu.common.exception.ServiceException;
import com.jichangxiu.common.utils.TokenUtils;
import com.jichangxiu.framework.mybatis.BaseServiceImpl;
import com.jichangxiu.server.platform.entity.dto.PlatformConfigQueryDto;
import com.jichangxiu.server.platform.entity.map.PlatformConfigBasic;
import com.jichangxiu.server.platform.entity.po.PlatformConfig;
import com.jichangxiu.server.platform.entity.po.PlatformTenant;
import com.jichangxiu.server.platform.entity.vo.PlatformConfigAddVo;
import com.jichangxiu.server.platform.entity.vo.PlatformConfigEditVo;
import com.jichangxiu.server.platform.entity.vo.PlatformConfigQueryVo;
import com.jichangxiu.server.platform.mapper.PlatformConfigMapper;
import com.jichangxiu.server.platform.service.PlatformConfigService;
import com.jichangxiu.server.platform.service.PlatformTenantService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * PlatformConfigServiceImpl:
 *
 * @author Jcx
 * @create 2023-03-08 21:17
 */
@Service
public class PlatformConfigServiceImpl extends BaseServiceImpl<PlatformConfigMapper, PlatformConfig> implements PlatformConfigService {

    @Resource
    private TokenUtils tokenUtils;

    @Resource
    private PlatformConfigMapper platformConfigMapper;

    @Resource
    private PlatformTenantService platformTenantService;

    /**
     * 新增配置
     *
     * @param platformConfigAddVo 配置视图对象
     * @return 是否成功
     */
    @Override
    public Boolean add(PlatformConfigAddVo platformConfigAddVo) {
        if (ObjectUtil.isEmpty(platformConfigAddVo)) {
            throw ServiceException.build("配置对象无效");
        }

        PlatformConfig platformConfig = PlatformConfigBasic.INSTANCE.toPlatformConfig(platformConfigAddVo);
        if (ObjectUtil.isEmpty(platformConfig)) {
            throw ServiceException.build("配置对象无效");
        }

        if ("PLATFORM_CONFIG".equals(platformConfig.getConfigType())) {
            PlatformTenant platformTenant = platformTenantService.getOne(new LambdaQueryWrapper<PlatformTenant>().eq(PlatformTenant::getTenantId, tokenUtils.getTenantId()));
            if (ObjectUtil.isEmpty(platformTenant)) {
                throw ServiceException.build("获取租户失败");
            }
            if (!platformTenant.getIsPlatform()) {
                throw ServiceException.build("非平台级租户不能创建平台级配置");
            }
        }

        if ("USER_CONFIG".equals(platformConfig.getConfigType())) {
            platformConfig.setUserId(tokenUtils.getSecurityUser().getUserId());
        }

        // code 必须唯一
        PlatformConfig dbPPlatformConfigByCode = getOne(new LambdaQueryWrapper<PlatformConfig>().eq(PlatformConfig::getConfigCode, platformConfig.getConfigCode()));
        if (ObjectUtil.isNotEmpty(dbPPlatformConfigByCode)) {
            throw ServiceException.build(platformConfig.getConfigName() + "该配置的标识重复");
        }

        // name 必须唯一
        PlatformConfig dbPPlatformConfigByName = getOne(new LambdaQueryWrapper<PlatformConfig>().eq(PlatformConfig::getConfigName, platformConfig.getConfigName()));
        if (ObjectUtil.isNotEmpty(dbPPlatformConfigByName)) {
            throw ServiceException.build(platformConfig.getConfigName() + "该配置的名称重复");
        }

        // key 必须唯一
        PlatformConfig dbPPlatformConfigByKey = getOne(new LambdaQueryWrapper<PlatformConfig>().eq(PlatformConfig::getConfigKey, platformConfig.getConfigKey()));
        if (ObjectUtil.isNotEmpty(dbPPlatformConfigByKey)) {
            throw ServiceException.build(platformConfig.getConfigName() + "该配置的名称重复");
        }

        platformConfig.setTenantId(tokenUtils.getTenantId());
        return save(platformConfig);
    }

    /**
     * 多选级联删除配置
     *
     * @param configIdList 配置ID列表
     * @return 是否成功
     */
    @Override
    public Boolean del(List<String> configIdList) {
        List<PlatformConfig> platformConfigList = list(new LambdaQueryWrapper<PlatformConfig>().in(PlatformConfig::getConfigId, configIdList));
        if (ObjectUtil.isEmpty(platformConfigList)) {
            throw ServiceException.build("数据库中不存在需要删除的记录");
        }

        PlatformTenant platformTenant = platformTenantService.getOne(new LambdaQueryWrapper<PlatformTenant>().eq(PlatformTenant::getTenantId, tokenUtils.getTenantId()));

        platformConfigList.forEach(platformConfig -> {
            if ("PLATFORM_CONFIG".equals(platformConfig.getConfigType())) {
                if (ObjectUtil.isEmpty(platformTenant)) {
                    throw ServiceException.build("获取租户失败");
                }
                if (!platformTenant.getIsPlatform()) {
                    throw ServiceException.build("非平台级租户不能删除平台级配置");
                }
            }
        });

        return removeBatchByIds(configIdList);
    }

    /**
     * 修改配置信息
     *
     * @param platformConfigEditVo 配置视图对象
     * @return 是否成功
     */
    @Override
    public Boolean edit(PlatformConfigEditVo platformConfigEditVo) {
        if (ObjectUtil.isEmpty(platformConfigEditVo)) {
            throw ServiceException.build("配置对象无效");
        }

        PlatformConfig platformConfig = PlatformConfigBasic.INSTANCE.toPlatformConfig(platformConfigEditVo);
        if (ObjectUtil.isEmpty(platformConfig)) {
            throw ServiceException.build("配置对象无效");
        }

        PlatformConfig dbPlatformConfig = getOne(new LambdaQueryWrapper<PlatformConfig>().eq(PlatformConfig::getConfigId, platformConfig.getConfigId()));
        if (ObjectUtil.isEmpty(dbPlatformConfig)) {
            throw ServiceException.build(platformConfig.getConfigName() + "该配置在数据库中不存在");
        }

        if ("PLATFORM_CONFIG".equals(dbPlatformConfig.getConfigType())) {
            PlatformTenant platformTenant = platformTenantService.getOne(new LambdaQueryWrapper<PlatformTenant>().eq(PlatformTenant::getTenantId, tokenUtils.getTenantId()));
            if (ObjectUtil.isEmpty(platformTenant)) {
                throw ServiceException.build("获取租户失败");
            }
            if (!platformTenant.getIsPlatform()) {
                throw ServiceException.build("非平台级租户不能修改平台级配置");
            }
        }

        // code 必须唯一
        if (!dbPlatformConfig.getConfigCode().equals(platformConfig.getConfigCode())) {
            PlatformConfig dbPPlatformConfigByCode = getOne(new LambdaQueryWrapper<PlatformConfig>().eq(PlatformConfig::getConfigCode, platformConfig.getConfigCode()));
            if (ObjectUtil.isNotEmpty(dbPPlatformConfigByCode)) {
                throw ServiceException.build(platformConfig.getConfigName() + "该配置的标识重复");
            }
        }

        // name 必须唯一
        if (!dbPlatformConfig.getConfigName().equals(platformConfig.getConfigName())) {
            PlatformConfig dbPPlatformConfigByName = getOne(new LambdaQueryWrapper<PlatformConfig>().eq(PlatformConfig::getConfigName, platformConfig.getConfigName()));
            if (ObjectUtil.isNotEmpty(dbPPlatformConfigByName)) {
                throw ServiceException.build(platformConfig.getConfigName() + "该配置的名称重复");
            }
        }

        // key 必须唯一
        if (!dbPlatformConfig.getConfigKey().equals(platformConfig.getConfigKey())) {
            PlatformConfig dbPPlatformConfigByKey = getOne(new LambdaQueryWrapper<PlatformConfig>().eq(PlatformConfig::getConfigKey, platformConfig.getConfigKey()));
            if (ObjectUtil.isNotEmpty(dbPPlatformConfigByKey)) {
                throw ServiceException.build(platformConfig.getConfigName() + "该配置的名称重复");
            }
        }

        BeanUtil.copyProperties(platformConfig, dbPlatformConfig, true);
        return updateById(dbPlatformConfig);
    }

    /**
     * 根据ID获取配置详情
     *
     * @param configId 配置ID
     * @return 配置详情
     */
    @Override
    public PlatformConfigQueryDto info(String configId) {
        PlatformConfig platformConfig = getOne(new LambdaQueryWrapper<PlatformConfig>().eq(PlatformConfig::getConfigId, configId));
        return PlatformConfigBasic.INSTANCE.toPlatformConfigQueryDto(platformConfig);
    }

    /**
     * 分页查询配置列表
     *
     * @param platformConfigQueryVo 配置视图对象
     * @return 分页配置列表
     */
    @Override
    public PageData<PlatformConfigQueryDto> pageList(PlatformConfigQueryVo platformConfigQueryVo) {
        Page<PlatformConfig> page = startPage();
        List<PlatformConfig> platformConfigList = platformConfigMapper.pageList(PlatformConfigBasic.INSTANCE.toPlatformConfig(platformConfigQueryVo), page);
        List<PlatformConfigQueryDto> platformConfigQueryDtoList = PlatformConfigBasic.INSTANCE.toPlatformConfigQueryDtoList(platformConfigList);
        return PageData.build(new Page<>(page.getCurrent(), page.getSize(), page.getTotal()), platformConfigQueryDtoList);
    }

    /**
     * 获取平台初始化配置
     *
     * @return 配置列表
     */
    @Override
    public List<PlatformConfigQueryDto> getInitPlatformConfig() {
        List<String> configKeyList = new ArrayList<>();
        configKeyList.add("OPEN_REGISTER");
        configKeyList.add("RESET_PASSWORD");
        configKeyList.add("PHONE_LOGIN");
        configKeyList.add("WECHAT_LOGIN");
        configKeyList.add("LOGIN_24_HOUR");
        List<PlatformConfig> platformConfigList = platformConfigMapper.getConfigList(null, null, configKeyList);
        return PlatformConfigBasic.INSTANCE.toPlatformConfigQueryDtoList(platformConfigList);
    }

    /**
     * 获取系统初始化配置
     *
     * @return 配置列表
     */
    @Override
    public List<PlatformConfigQueryDto> getInitSystemConfig() {
        List<String> configKeyList = new ArrayList<>();
        configKeyList.add("SYSTEM_NAME");
        List<PlatformConfig> platformConfigList = platformConfigMapper.getConfigList(tokenUtils.getTenantId(), null, configKeyList);
        return PlatformConfigBasic.INSTANCE.toPlatformConfigQueryDtoList(platformConfigList);
    }

    /**
     * 跨平台获取平台配置参数值
     *
     * @param configCode 配置标识
     * @param configKey  配置键名
     * @return 配置键值
     */
    @Override
    public String getPlatformConfigValue(String configCode, String configKey) {
        return platformConfigMapper.getConfigValue(null, configCode, configKey);
    }

    /**
     * 跨平台获取平台配置参数值
     *
     * @param configCode   配置标识
     * @param configKey    配置键名
     * @param defaultValue 默认值
     * @return 配置键值
     */
    @Override
    public String getPlatformConfigValue(String configCode, String configKey, String defaultValue) {
        String platformConfigValue = getPlatformConfigValue(configCode, configKey);
        return StrUtil.isEmpty(platformConfigValue) ? defaultValue : platformConfigValue;
    }

    /**
     * 获取指定租户的配置
     *
     * @param tenantId   租户ID
     * @param configCode 配置标识
     * @param configKey  配置键名
     * @return 配置键值
     */
    @Override
    public String getConfigValue(String tenantId, String configCode, String configKey) {
        return platformConfigMapper.getConfigValue(tenantId, configCode, configKey);
    }

    /**
     * 获取指定租户的配置
     *
     * @param tenantId     租户ID
     * @param configCode   配置标识
     * @param configKey    配置键名
     * @param defaultValue 默认值
     * @return 配置键值
     */
    @Override
    public String getConfigValue(String tenantId, String configCode, String configKey, String defaultValue) {
        String platformConfigValue = getConfigValue(tenantId, configCode, configKey);
        return StrUtil.isEmpty(platformConfigValue) ? defaultValue : platformConfigValue;
    }

}
